{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 符号代数运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sin, log\n",
    "from abc import ABC, abstractmethod\n",
    "import math\n",
    "from math import sin, cos, log"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import *\n",
    "from sympy.core.core import *\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "y*(x + 3)\n",
      "4*y\n",
      "2*x\n",
      "x**3\n"
     ]
    }
   ],
   "source": [
    "Mul(Symbol('y'), Add(3, Symbol(\"x\")))\n",
    "y = Symbol('y')\n",
    "x = Symbol('x')\n",
    "print(y*(3+x))\n",
    "print(y*(3+x).subs(x, 1))\n",
    "print((x**2).diff(x))\n",
    "print((3*x**2).integrate(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Integer(0).integrate(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "_function_bindings = {\n",
    "    \"sin\": math.sin,\n",
    "    \"cos\": math.cos,\n",
    "    \"ln\": math.log,\n",
    "    \"sqrt\": math.sqrt\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Expression(ABC):\n",
    "    @abstractmethod\n",
    "    def evaluate(self, **buildings):\n",
    "        pass\n",
    "    \n",
    "    @abstractmethod\n",
    "    def expend(self):\n",
    "        pass\n",
    "    \n",
    "    @abstractmethod\n",
    "    def display(self):\n",
    "        pass\n",
    "    \n",
    "    def __repr__(self):\n",
    "        return self.display()\n",
    "    \n",
    "    @abstractmethod\n",
    "    def derivative(self, var):\n",
    "        pass\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Power(Expression):\n",
    "    # 幂运算\n",
    "    def __init__(self, base, exponent):\n",
    "        self.base = base\n",
    "        self.exponent = exponent\n",
    "        \n",
    "    def evaluate(self, **buildings):\n",
    "        return self.base.evaluate(**buildings) ** self.exponent.evaluate(**buildings)\n",
    "    \n",
    "    def expend(self):\n",
    "        return self\n",
    "    \n",
    "    def display(self):\n",
    "        return \"Power({},{})\".format(self.base.display(), self.exponent.display())\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        if isinstance(self.exponent, Number):\n",
    "            power_rule = Product(Number(self.exponent.number), Power(self.base, Number(self.exponent.number - 1)))\n",
    "        \n",
    "            return Product(self.base.derivative(var), power_rule)\n",
    "    \n",
    "        elif isinstance(self.base, Number):\n",
    "            exponential_rule = Product(Apply(Function(\"ln\"), Number(self.base.number)), self)\n",
    "            \n",
    "            return Product(self.exponent.derivative(var), exponential_rule)\n",
    "        \n",
    "        else:\n",
    "            raise Exception(\"err\")\n",
    "    \n",
    "    \n",
    "class Number(Expression):\n",
    "    # 指定数字\n",
    "    def __init__(self, number):\n",
    "        self.number = number\n",
    "        \n",
    "    def evaluate(self, **buildings):\n",
    "        return self.number\n",
    "    \n",
    "    def expend(self):\n",
    "        return self\n",
    "    \n",
    "    def display(self):\n",
    "        return \"Number{}\".format(self.number)\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        return Number(0)\n",
    "  \n",
    "class Variable(Expression):\n",
    "    # 指定变量名\n",
    "    def __init__(self, symbol):\n",
    "        self.symbol = symbol\n",
    "        \n",
    "    def evaluate(self, **buildings):\n",
    "        try:\n",
    "            return buildings[self.symbol]\n",
    "        except: \n",
    "            raise KeyError(\"Variable '{}' is not bound.\".format(self.symbol))\n",
    "            \n",
    "    def expend(self):\n",
    "        return self\n",
    "    \n",
    "    def display(self):\n",
    "        return \"Variable(\\\"{}\\\")\".format(self.symbol)\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        if self.symbol == var.symbol:\n",
    "            return Number(1)\n",
    "        \n",
    "        else:\n",
    "            return Number(0)\n",
    "            \n",
    "  \n",
    "class Product(Expression):\n",
    "    # 乘法运算\n",
    "    def __init__(self, exp1, exp2):\n",
    "        self.exp1 = exp1\n",
    "        self.exp2 = exp2\n",
    "        \n",
    "    def evaluate(self, **buildings):\n",
    "        return self.exp1.evaluate(**buildings) * self.exp2.evaluate(**buildings)\n",
    "    \n",
    "    def expend(self):\n",
    "        # 乘法分配律\n",
    "        expanded1 = self.exp1.expend()\n",
    "        expanded2 = self.exp2.expend()\n",
    "        if isinstance(expanded1, Sum):\n",
    "            return Sum(*[Product(e, expanded2).expend() for e in expanded1.exps])\n",
    "        \n",
    "        elif isinstance(expanded2, Sum):\n",
    "            return Sum(*[Product(expanded1, e) for e in expanded2])\n",
    "        \n",
    "        else:\n",
    "            return Product(expanded1, expanded2)\n",
    "        \n",
    "    def display(self):\n",
    "        return \"Product({},{})\".format(self.exp1.display(), self.exp2.display())\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        if isinstance(self.expanded1, Number):\n",
    "            return Product(Number(self.expanded1.number), self.expanded2.derivative(var))\n",
    "        \n",
    "        elif isinstance(self.expanded2, Number):\n",
    "            return Product(Number(self.expanded2.number), self.expanded1.derivative(var))\n",
    "        \n",
    "        else:\n",
    "            return Sum(Product(self.expanded1, self.expanded2.derivative(var)), Product(self.expanded2, self.expanded1.derivative(var)))\n",
    "        \n",
    "    \n",
    "class Sum(Expression):\n",
    "    # 加法运算\n",
    "    def __init__(self, *exps):\n",
    "        self.exps = exps\n",
    "        \n",
    "    def evaluate(self, **buildings):\n",
    "        return sum([i.evaluate(**buildings) for i in self.exps])\n",
    "    \n",
    "    def expend(self):\n",
    "        return Sum(*[exp.expend() for exp in self.exps])\n",
    "    \n",
    "    def display(self):\n",
    "        return \"Sum({})\".format(\",\".join([e.display() for e in self.exps]))\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        return Sum(*[exp.derivative(var) for exp in self.exps])\n",
    "        \n",
    "class Function():\n",
    "    # 特殊方法运算(sin,log,cos.....)\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        \n",
    "    def expend(self):\n",
    "        return self\n",
    "    \n",
    "\n",
    "class Apply(Expression):\n",
    "    # 为特殊方法传入参数\n",
    "    def __init__(self, function, argument):\n",
    "        self.function = function\n",
    "        self.argument = argument\n",
    "        \n",
    "    def evaluate(self, **buildings):   \n",
    "        return _function_bindings[self.function.name](self.argument.evaluate(**buildings))\n",
    "    \n",
    "    def expend(self):\n",
    "        return Apply(self.function, self.argument.expend())\n",
    "    \n",
    "    \n",
    "    def display(self):\n",
    "        return \"Apply(Function(\\\"{}\\\"),{})\".format(self.function.name, self.argument.display())\n",
    "    \n",
    "    \n",
    "    def derivative(self, var):\n",
    "        pass\n",
    "    \n",
    "        \n",
    "class Quotient(Exception):\n",
    "    # 表达式相除\n",
    "    def __init__(self, numerator, denominator):\n",
    "        self.numerator = numerator\n",
    "        self.denominator = denominator\n",
    "    \n",
    "    def evaluate(self, **buildings):\n",
    "        return self.numerator.evaluate(**buildings)/self.denominator.evaluate(**buildings)\n",
    "    \n",
    "    def expend(self):\n",
    "        return self\n",
    "    \n",
    "    def display(self):\n",
    "        return \"Quotient({},{})\".format(self.numerator.display(), self.denominator.display())\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        pass\n",
    "        \n",
    "    \n",
    "class Difference(Exception):\n",
    "    # 表达式相减\n",
    "    def __init__(self, exp1, exp2):\n",
    "        self.exp1 = exp1\n",
    "        self.exp2 = exp2\n",
    "        \n",
    "    def evaluate(self, **buildings):\n",
    "        return self.exp1.evaluate(**buildings)-self.exp2.evaluate(**buildings)\n",
    "    \n",
    "    def expend(self):\n",
    "        return self\n",
    "    \n",
    "    def display(self):\n",
    "        return \"Different({},{})\".format(self.exp1.display(), self.exp2.display())\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        pass\n",
    "        \n",
    "class Negative(Exception):\n",
    "    # 表达式取相反数\n",
    "    def __init__(self, exp):\n",
    "        self.exp = exp\n",
    "        \n",
    "    def evaluate(self, **buildings):\n",
    "        return -(self.exp.evaluate(**buildings))\n",
    "    \n",
    "    def expend(self):\n",
    "        return self\n",
    "    \n",
    "    def display(self):\n",
    "        return \"Negative{}\".format(self.exp.display())\n",
    "    \n",
    "    def derivative(self, var):\n",
    "        pass\n",
    "        \n",
    "A = Variable(\"a\")\n",
    "B = Variable(\"b\")\n",
    "C = Variable(\"c\")\n",
    "Sqrt = Function(\"sqrt\")\n",
    "        \n",
    "f1 = Product(Sum(Product(Number(3), Power(Variable('x'), Number(2))), Variable('x')), Apply(Function(\"sin\"), Variable('x')))\n",
    "f2 = Quotient(Sum(Variable(\"a\"), Variable(\"b\")), Number(2))\n",
    "f3 = Difference(Power(Variable(\"b\"), Number(2)), Product(Number(4), Product(Variable(\"a\"), Variable(\"c\"))))\n",
    "f4 = Negative(Sum(Power(Variable(\"x\"), Number(2)), Variable(\"y\")))\n",
    "f5 = Quotient(Sum(Negative(B), Apply(Sqrt, Difference(Power(B, Number(2)), Product(Number(4), Product(A, C))))), Product(Number(2), A))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "_var = Variable('placeholder variable')\n",
    "\n",
    "_derivatives = {\n",
    "    \"sin\" : Apply(Function(\"cos\"), _var),\n",
    "    \"cos\" : Product(Number(-1), Apply(Function(\"sin\"), _var)),\n",
    "    \"ln\" : Quotient(Number(1), _var),\n",
    "    \"sqrt\": Quotient(Number(1), Product(Number(2), Apply(Function(\"sqrt\"), _var)))\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [],
   "source": [
    "def distanct_variables(exp):\n",
    "    # 返回表达式中的变量名称\n",
    "    if isinstance(exp, Variable):\n",
    "        return set(exp.symbol)\n",
    "    elif isinstance(exp, Number):\n",
    "        return set()\n",
    "    elif isinstance(exp, Sum):\n",
    "        return set().union(*[distanct_variables(exp) for exp in exp.exps])\n",
    "    elif isinstance(exp, Difference):\n",
    "        return distanct_variables(exp.exp1).union(distanct_variables(exp.exp2))\n",
    "    elif isinstance(exp, Power):\n",
    "        return distanct_variables(exp.base).union(distanct_variables(exp.exponent))\n",
    "    elif isinstance(exp, Product):\n",
    "        return distanct_variables(exp.exp1).union(distanct_variables(exp.exp2))\n",
    "    elif isinstance(exp, Apply):\n",
    "        return distanct_variables(exp.argument)\n",
    "    elif isinstance(exp, Negative):\n",
    "        return distanct_variables(exp.exp)\n",
    "    elif isinstance(exp, Quotient):\n",
    "        return distanct_variables(exp.numerator).union(distanct_variables(exp.denominator))\n",
    "    else:\n",
    "        raise TypeError(\"Not a valid expression\")\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "def contains(expression, variable):\n",
    "    if isinstance(expression, Variable):\n",
    "        return expression.symbol == variable\n",
    "    \n",
    "    elif isinstance(expression, Number):\n",
    "        return False\n",
    "    \n",
    "    elif isinstance(expression, Power):\n",
    "        return contains(expression.base, variable) or contains(expression.exponent, variable)\n",
    "    \n",
    "    elif isinstance(expression, Product):\n",
    "        return contains(expression.exp1, variable) or contains(expression.exp2, variable)\n",
    "    \n",
    "    elif isinstance(expression, Sum):\n",
    "        return any([contains(i, variable) for i in expression.exps])\n",
    "    \n",
    "    elif isinstance(expression, Apply):\n",
    "        return contains(expression.argument, variable)\n",
    "    \n",
    "    elif isinstance(expression, Quotient):\n",
    "        return contains(expression.numerator, variable) or contains(expression.denominator, variable)\n",
    "    \n",
    "    elif isinstance(expression, Difference):\n",
    "        return contains(expression.exp1, variable) or contains(expression.exp2, variable)\n",
    "    \n",
    "    elif isinstance(expression, Negative):\n",
    "        return contains(expression.exp)\n",
    "    \n",
    "    else:\n",
    "        raise TypeError(\"Not a valid expression.\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "def distinct_functions(exp):\n",
    "    if isinstance(exp, Apply):\n",
    "        return set([exp.function.name]).union(distinct_functions(exp.argument))\n",
    "    \n",
    "    elif isinstance(exp, Number):\n",
    "        return set()\n",
    "    \n",
    "    elif isinstance(exp, Variable):\n",
    "        return set()\n",
    "    \n",
    "    elif isinstance(exp, Product):\n",
    "        return distinct_functions(exp.exp1).union(distinct_functions(exp.exp2))\n",
    "    \n",
    "    elif isinstance(exp, Sum):\n",
    "        return set().union(*[distinct_functions(exp) for exp in exp.exps])\n",
    "    \n",
    "    elif isinstance(exp, Quotient):\n",
    "        return distinct_functions(exp.numerator).union(distinct_functions(exp.denominator))\n",
    "    \n",
    "    elif isinstance(exp, Difference):\n",
    "        return distinct_functions(exp.exp1).union(distinct_functions(exp.exp2))\n",
    "    \n",
    "    elif isinstance(exp, Power):\n",
    "        return distinct_functions(exp.base).union(distinct_functions(exp, exponent))\n",
    "    \n",
    "    else:\n",
    "        assert TypeError(\"Not a valid expression.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "def contains_sum(exp):\n",
    "    if isinstance(exp, Sum):\n",
    "        return True\n",
    "    \n",
    "    elif isinstance(exp, Variable):\n",
    "        return False\n",
    "    \n",
    "    elif isinstance(exp, Number):\n",
    "        return False\n",
    "    \n",
    "    elif isinstance(exp, Power):\n",
    "        return contains_sum(exp.base) or contains_sum(exp.exponent)\n",
    "    \n",
    "    elif isinstance(exp, Product):\n",
    "        return contains_sum(exp.exp1) or contains_sum(exp.exp2)\n",
    "    \n",
    "    elif isinstance(exp, Difference):\n",
    "        return contains_sum(exp.exp1) or contains_sum(exp.exp2)\n",
    "    \n",
    "    elif isinstance(exp, Quotient):\n",
    "        return contains_sum(exp.numerator) or contains_sum(exp.denominator)\n",
    "    \n",
    "    elif isinstance(exp, Apply):\n",
    "        return contains_sum(exp.argument)\n",
    "    \n",
    "    else:\n",
    "        assert TypeError(\"Not a valid expression.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Power(Number3,Number5)\n"
     ]
    }
   ],
   "source": [
    "p = Power(Number(3), Number(5))\n",
    "print(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sum(Apply(Function(\"sin\"),Variable(\"x\")),Apply(Function(\"cos\"),Variable(\"y\")))\n",
      "{'cos', 'sin'}\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "f = Function(\"sin\")\n",
    "f1 = Function(\"cos\")\n",
    "x = Variable(\"x\")\n",
    "y = Variable(\"y\")\n",
    "\n",
    "a = Apply(f, x)\n",
    "b = Apply(f1, y)\n",
    "\n",
    "s = Sum(a, b)\n",
    "print(s)\n",
    "\n",
    "print(distinct_functions(s))\n",
    "print(contains_sum(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'b', 'a', 'c'}\n"
     ]
    }
   ],
   "source": [
    "b = Sum(Number(1), Number(2), Number(3))\n",
    "distanct_variables(b)\n",
    "print(distanct_variables(f3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4, 5}\n",
      "{'c', 'a', 'abvf'}\n",
      "{'c', 'v', 'a', 'f'}\n"
     ]
    }
   ],
   "source": [
    "a = set([1, 2, 3, 4]).union([1, 2, 3, 4, 5])\n",
    "b = set().union([\"a\", \"abvf\", \"c\"])\n",
    "c = set().union(*[\"a\", \"avvf\", \"c\"])\n",
    "\n",
    "print(a)\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{<__main__.Number object at 0x0000026D8D1D06A0>, <__main__.Number object at 0x0000026D8D1D0CC0>, <__main__.Number object at 0x0000026D8D1D0748>}\n"
     ]
    }
   ],
   "source": [
    "f1.evaluate(x=3)\n",
    "f3.evaluate(a=1, b=2, c=3)\n",
    "a = set.union({i for i in b.exps})\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.1411200080598672\n",
      "4.5\n",
      "1.0\n",
      "2\n",
      "-10\n"
     ]
    }
   ],
   "source": [
    "a = Number(2)\n",
    "b = Number(9)\n",
    "c = Function(\"sin\")\n",
    "\n",
    "s1 = Variable(\"x\")\n",
    "s2 = Variable(\"y\")\n",
    "\n",
    "n1 = Apply(c, s1)\n",
    "n2 = Quotient(b, a)\n",
    "n3 = Quotient(s1, a)\n",
    "n4 = Difference(s1, s2)\n",
    "n5 = Negative(s1)\n",
    "\n",
    "\n",
    "print(n1.evaluate(x=3))\n",
    "print(n2.evaluate())\n",
    "print(n3.evaluate(x=2))\n",
    "print(n4.evaluate(x=4, y=2))\n",
    "print(n5.evaluate(x=10))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = Variable(\"y\")\n",
    "d.evaluate(y=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "18\n",
      "512\n",
      "6\n",
      "11\n",
      "7\n",
      "-0.5440211108893698\n"
     ]
    }
   ],
   "source": [
    "a = Number(2)\n",
    "b = Number(9)\n",
    "\n",
    "s1 = Variable(\"x\")\n",
    "s2 = Variable(\"y\")\n",
    "\n",
    "c = Power(a, b)\n",
    "d = Product(a, b)\n",
    "e = Product(s1, s2)\n",
    "f = Sum(a, b)\n",
    "g = Sum(s1, s2)\n",
    "h = Apply(sin, s1)\n",
    "\n",
    "print(d.evaluate())\n",
    "print(c.evaluate())\n",
    "print(e.evaluate(x=2, y=3))\n",
    "print(f.evaluate())\n",
    "print(g.evaluate(x=3, y=4))\n",
    "print(h.evaluate(x=10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.1411200080598672"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f = Function(sin)\n",
    "f.latex(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<__main__.Apply at 0x28f14df5240>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def f(y, z):\n",
    "    return log(y**z)\n",
    "\n",
    "Apply(log, Power(Variable('y'), Number('z')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-6-eac15a659643>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-6-eac15a659643>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    return **kwargs\u001b[0m\n\u001b[1;37m            ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "def my_function(**kwargs):\n",
    "    return \n",
    "\n",
    "print(my_function(x=1, y=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
